﻿#define _CRT_SECURE_NO_WARNINGS 1

using namespace std;
#include <iostream>
#include<functional>

//int f(int a, int b)
//{
//	return a + b;
//}
//
//struct Functor
//{
//public:
//	int operator() (int a, int b)
//	{
//		return a + b;
//	}
//};
//
//class Plus
//{
//public:
//	Plus(int n = 10)
//		:_n(n)
//	{
//	}
//
//	static int plusi(int a, int b)
//	{
//		return a + b;
//	}
//
//	double plusd(double a, double b)
//	{
//		return (a + b) * _n;
//	}
//
//private:
//	int _n;
//};
//
//int main()
//{
//	// 包装各种可调⽤对象
//	function<int(int, int)> f1 = f; //包装函数指针
//	function<int(int, int)> f2 = Functor(); //包装仿函数对象
//	function<int(int, int)> f3 = [](int a, int b) {return a + b; }; //包装lambda
//	cout << f1(1, 1) << endl;
//	cout << f2(1, 1) << endl;
//	cout << f3(1, 1) << endl;
//
//	// 包装静态成员函数
//	// 成员函数要指定类域并且前⾯加&才能获取地址
//	function<int(int, int)> f4 = &Plus::plusi;
//	cout << f4(1, 1) << endl;
//
//	// 包装普通成员函数
//	// 普通成员函数还有⼀个隐含的this指针参数，所以绑定时传对象或者对象的指针过去都可以
//	function<double(Plus*, double, double)> f5 = &Plus::plusd;
//	Plus pd;
//	cout << f5(&pd, 1.1, 1.1) << endl;
//	function<double(Plus&, double, double)> f6 = &Plus::plusd;
//	cout << f6(pd, 1.1, 1.1) << endl;
//
//	function<double(Plus&&, double, double)> f7 = &Plus::plusd;
//	cout << f7(move(pd), 1.1, 1.1) << endl;
//	cout << f7(Plus(), 1.1, 1.1) << endl;
//
//	return 0;
//}


#include <string>
#include <vector>
#include <stack>
#include <map>

// 传统⽅式的实现
class Solution {
public:
	int evalRPN(vector<string>& tokens) {
		stack<int> st;
		for (auto& str : tokens)
		{
			if (str == "+" || str == "-" || str == "*" || str == "/")
			{
				int right = st.top();
				st.pop();
				int left = st.top();
				st.pop();
				switch (str[0])
				{
				case '+':
					st.push(left + right);
					break;
				case '-':
					st.push(left - right);
					break;
				case '*':
					st.push(left * right);
					break;
				case '/':
					st.push(left / right);
					break;
				}
			}
			else
			{
				st.push(stoi(str));
			}
		}
		return st.top();
	}
};
// 使⽤map映射string和function的⽅式实现
// 这种⽅式的最⼤优势之⼀是⽅便扩展，假设还有其他运算，我们增加map中的映射即可
class Solution {
public:
	int evalRPN(vector<string>& tokens) {
		stack<int> st;
		// function作为map的映射可调⽤对象的类型
		map<string, function<int(int, int)>> opFuncMap = {
		{"+", [](int x, int y) {return x + y; }},
		{"-", [](int x, int y) {return x - y; }},
		{"*", [](int x, int y) {return x * y; }},
		{"/", [](int x, int y) {return x / y; }}
		};

		for (auto& str : tokens)
		{
			if (opFuncMap.count(str)) // 操作符
			{
				int right = st.top();
				st.pop();
				int left = st.top();
				st.pop();
				//opFuncMap[str]:
				int ret = opFuncMap[str](left, right); 
				st.push(ret);
			}
			else
			{
				st.push(stoi(str));
			}
		}
		return st.top();
	}
};

